package com.example.smartmedicalsystem.service;

import com.example.smartmedicalsystem.entity.*;
import com.example.smartmedicalsystem.repository.*;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.sql.Timestamp;
import java.util.List;

@Service
@RequiredArgsConstructor
@Transactional
public class AppointmentService {
    private final AppointmentRepository appointmentRepo;
    private final MedicineRepository medicineRepo;
    private final MessageService messageService;
    private final UserRepository userRepo;
    private final ScheduleRepository scheduleRepo;
    private final DoctorRepository doctorRepo;
    private final MedicalRecordRepository medicalRecordRepo;

    public Appointment createAppointment(AppointmentRequest request) {
        User patient = userRepo.findById(request.getPatientId())
                .orElseThrow(() -> new RuntimeException("患者不存在"));
        Schedule schedule = scheduleRepo.findById(request.getScheduleId())
                .orElseThrow(() -> new RuntimeException("排班不存在"));

        if (schedule.getAvailableSlots() <= 0) {
            throw new RuntimeException("该时段已无可用预约位置");
        }

        Appointment appointment = new Appointment();
        appointment.setPatient(patient);
        appointment.setSchedule(schedule);
        appointment.setStatus(Appointment.Status.PENDING);
        appointment.setCreatedAt(new Timestamp(System.currentTimeMillis()));

        schedule.setAvailableSlots(schedule.getAvailableSlots() - 1);
        scheduleRepo.save(schedule);

        messageService.sendMessage(
                null,
                schedule.getDoctor().getUser().getId(),
                "新预约通知：患者 " + patient.getUsername() + " 预约了您的 " + schedule.getScheduleDate() + " 的班次"
        );

        return appointmentRepo.save(appointment);
    }

    public void confirmAppointment(Long appointmentId, Long doctorId) {
        Appointment appointment = appointmentRepo.findById(appointmentId)
                .orElseThrow(() -> new RuntimeException("预约不存在"));

        // 使用 findByUser_Id 方法查询医生
        Doctor doctor = doctorRepo.findByUser_Id(doctorId)
                .orElseThrow(() -> new RuntimeException("医生不存在"));

        // 验证权限
        if (!appointment.getSchedule().getDoctor().getId().equals(doctor.getId())) {
            throw new RuntimeException("无权操作该预约");
        }

        // 更新预约状态
        appointment.setStatus(Appointment.Status.CONFIRMED);
        appointmentRepo.save(appointment);

        // 发送消息
        messageService.sendMessage(
                doctorId,
                appointment.getPatient().getId(),
                "您的预约 #" + appointmentId + " 已被医生确认"
        );
    }

    public MedicalRecord completeAppointment(Long appointmentId, CompleteRequest request) {
        Appointment appointment = appointmentRepo.findById(appointmentId)
                .orElseThrow(() -> new RuntimeException("预约不存在"));

        request.getMedicines().forEach(med -> {
            Medicine medicine = medicineRepo.findById(med.getMedicineId())
                    .orElseThrow(() -> new RuntimeException("药品不存在"));
            if (medicine.getStock() < med.getQuantity()) {
                throw new RuntimeException(medicine.getName() + " 库存不足");
            }
        });

        request.getMedicines().forEach(med -> {
            Medicine medicine = medicineRepo.findById(med.getMedicineId()).get();
            medicine.setStock(medicine.getStock() - med.getQuantity());
            medicineRepo.save(medicine);
        });

        MedicalRecord record = new MedicalRecord();
        record.setDiagnosis(request.getDiagnosis());
        record.setPrescription(request.getPrescription());
        record.setAppointment(appointment);
        MedicalRecord savedRecord = medicalRecordRepo.save(record);

        appointment.setStatus(Appointment.Status.COMPLETED);
        appointment.setMedicalRecord(savedRecord);
        appointmentRepo.save(appointment);

        messageService.sendMessage(
                appointment.getSchedule().getDoctor().getUser().getId(),
                appointment.getPatient().getId(),
                "您的预约 #" + appointmentId + " 已完成，点击查看诊断结果"
        );

        return savedRecord;
    }

    @Data
    public static class AppointmentRequest {
        private Long patientId;
        private Long scheduleId;
    }

    @Data
    public static class CompleteRequest {
        private String diagnosis;
        private String prescription;
        private List<MedicineRequest> medicines;

        @Data
        public static class MedicineRequest {
            private Long medicineId;
            private int quantity;
        }
    }
}